#include "FormatModel.h"
#include <QFileInfo>
#include <QMessageBox>
#include "format/formatmanager.h"

using namespace std;

FormatModel::FormatModel(QString file, QObject *parent)
    : QAbstractItemModel{parent}
{
    FERange range{};
    root_item_ = new FormatItem(nullptr, range, nullptr, nullptr, FormatItem::kFormat, "root", "");

    top_buffer_ = newFileFEBuffer(QFileInfo(file).fileName().toStdString().c_str(), file.toStdString().c_str());
    range.buffer = top_buffer_;
    range.bit_offset = 0;
    range.bit_len = top_buffer_->data_len << 3;

    auto top_format = FormatManager::getFormatForSuffix(QFileInfo(file).suffix());
    if (!top_format) {
        QMessageBox::warning(nullptr, "Warning", "not find matched format");
        return;
    }

    auto top_item = new FormatItem(top_format, range, nullptr, nullptr, FormatItem::kFormat, top_format->name(), "", root_item_);
    root_item_->appendChild(top_item);

    top_item->constructTree();
}

FormatModel::~FormatModel()
{
    if (root_item_) {
        delete root_item_;
        root_item_ = nullptr;
    }

    if (top_buffer_) {
        deleteFEBuffer(top_buffer_);
        top_buffer_ = nullptr;
    }
}

QModelIndex FormatModel::index(int row, int column, const QModelIndex& parent) const {
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    FormatItem* parentItem = getItem(parent);
    FormatItem* childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    return QModelIndex();
}

QModelIndex FormatModel::parent(const QModelIndex& index) const  {
    if (!index.isValid())
        return QModelIndex();

    FormatItem* childItem = getItem(index);
    FormatItem* parentItem = childItem->parent();

    if (parentItem == root_item_)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

int FormatModel::rowCount(const QModelIndex& parent) const  {
    FormatItem* parentItem = getItem(parent);
    return parentItem->childCount();
}

int FormatModel::columnCount(const QModelIndex& parent) const  {
    Q_UNUSED(parent);
    return 1; // 只有一列数据
}

QVariant FormatModel::data(const QModelIndex& index, int role) const  {
//    if (!index.isValid())
//        return QVariant();

    FormatItem* item = getItem(index);
    if (role == Qt::DisplayRole) {
//        qDebug() << "data" << item->data(index.column());
        return item->data(index.column());
    }

    return QVariant();
}

void FormatModel::showItem(const QModelIndex &index)
{
    if (index.isValid()) {
        FormatItem* item = static_cast<FormatItem*>(index.internalPointer());
        if (item) item->show();
    }
}

FormatItem* FormatModel::getItem(const QModelIndex& index) const {
    if (index.isValid()) {
        FormatItem* item = static_cast<FormatItem*>(index.internalPointer());
        if (item)
            return item;
    }
    return root_item_;
}
